ACecere (Normal User)
Newbie
Messaggi: 6
Iscritto: 24/02/2014
|
Salve a tutti,
è da qualche settimana che combatto con questo errore ed , essendo ormai sfiduciato, mi rivolgo a voi
In pratica, dopo circa 2 ore di esecuzione, mi si presenta l'errore "Risorse di sistema insufficienti"..
Il codice è il seguente :
Codice sorgente - presumibilmente VB.NET |
Public Sub Lettura_Dati() Dim Database As String = INIRead("C:\Config.ini", "Percorsi", "ConnectionString") + INIRead("C:\Config.ini", "Percorsi", "NomeDB") Dim Query, Query2 As String Dim Cn As New OleDbConnection(Database) Cn.Open() Query = "Select Descrizione from Articoli group by Genere" Dim Conn As New OleDb.OleDbCommand(Query, Cn) Dim Rs As OleDb.OleDbDataReader = Conn.ExecuteReader() While Rs.Read '############ TESTATE CAMPIONATO text2.text = Rs("Descrizione") Query2 = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'" Dim Conn2 As New OleDb.OleDbCommand(Query2, Cn) Dim rs2 As OleDbDataReader = Conn2.ExecuteReader While rs2.Read '################################ INCONTRI text1.text = rs2("Stato") End While rs2.Close() rs2 = Nothing Conn2.Dispose() End While Rs.Close() Rs = Nothing Cn.Dispose() Conn.Dispose() End Sub
|
L'errore me lo segnala sull'istruzione
Codice sorgente - presumibilmente C# / VB.NET |
Dim rs2 As OleDbDataReader = Conn2.ExecuteReader
|
Potreste aiutarmi a capire cosa c'è di errato nel codice ?
Grazie anticipatamente! |
|
Snogar (Normal User)
Pro
Messaggi: 145
Iscritto: 09/01/2012
|
prova a mettere un blocco try e metti le chiusure degli elementi del database nel finaly tanto per iniziare.
pio la conn2 la distruggi ad ogni ciclo while ....non ne capisco il senso
|
|
ACecere (Normal User)
Newbie
Messaggi: 6
Iscritto: 24/02/2014
|
pensi che così vada meglio ?
Codice sorgente - presumibilmente VB.NET |
Dim Database As String = INIRead("C:\Config.ini", "Percorsi", "ConnectionString") + INIRead("C:\Config.ini", "Percorsi", "NomeDB") Dim Query, Query2 As String Dim Cn As New OleDbConnection(Database) Cn.Open() Query = "Select Descrizione from Articoli group by Genere" Dim Conn As New OleDb.OleDbCommand(Query, Cn) Try Dim Rs As OleDb.OleDbDataReader = Conn.ExecuteReader() While Rs.Read text2.text = Rs("Descrizione") Query2 = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'" Dim Conn2 As New OleDb.OleDbCommand(Query2, Cn) Dim rs2 As OleDbDataReader = Conn2.ExecuteReader While rs2.Read text1.text = rs2("Stato") End While rs2.Close() rs2 = Nothing End While Catch es As Exception My.Computer.FileSystem.WriteAllText("C:\Log.txt", "Errore", True) Finally Rs.Close() Rs = Nothing Cn.Dispose() Conn.Dispose() Conn2.Dispose() End Try
|
|
|
Ultimo (Member)
Guru
Messaggi: 880
Iscritto: 22/05/2010
|
Risorse di sistema insuficenti = Mamma dammi i soldi che devo comprare altra RAM
If ok Then GOTO Avanza else GOTO Inizia
|
|
ACecere (Normal User)
Newbie
Messaggi: 6
Iscritto: 24/02/2014
|
16 Gb penso che bastino.. o no ?
|
|
Qwertj (Dev Team)
Guru
Messaggi: 678
Iscritto: 30/05/2011
|
Postato originariamente da Ultimo:
Risorse di sistema insuficenti = Mamma dammi i soldi che devo comprare altra RAM |
O come buttare via i soldi spegnendo il cervello
Codice sorgente - presumibilmente VB.NET |
While Rs.Read text2.text = Rs("Descrizione") Query2 = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'" Dim Conn2 As New OleDb.OleDbCommand(Query2, Cn) Dim rs2 As OleDbDataReader = Conn2.ExecuteReader While rs2.Read text1.text = rs2("Stato") End While rs2.Close() rs2 = Nothing End While
|
Allocare memoria in un ciclo, specialmente se si ripete così a lungo, è una PESSIMA pratica.
Se sei fortunato hai la GC che sputa sangue e un bel 200x di moltiplicatore sul tempo di esecuzione, se sei sfortunato (come nel tuo caso) finisci bellamente lo spazio in memoria.
Prova una cosa così
Codice sorgente - presumibilmente VB.NET |
Dim Database As String = INIRead("C:\Config.ini", "Percorsi", "ConnectionString") + INIRead("C:\Config.ini", "Percorsi", "NomeDB") 'Query1 e Query2 sono inutili Dim Cn As New OleDbConnection(Database) Cn.Open() Dim Conn As New OleDb.OleDbCommand("Select Descrizione from Articoli group by Genere", Cn) Try Dim Rs As OleDb.OleDbDataReader = Conn.ExecuteReader() Dim Conn2 As New OleDb.OleDbCommand() 'istanziato >una volta sola< Dim rs2 As OleDbDataReader Conn2.Connection = Cn While Rs.Read() Try text2.text = Rs("Descrizione") 'sovrascrivo semplicemente la query senza creare un nuovo oggetto ogni volta Conn2.CommandText = "Select Stato from Articoli Where Descrizione like '" & Rs("Descrizione") & "'" rs2 = Conn2.ExecuteReader() While rs2.Read() text1.text = rs2("Stato") End While Catch es As OutOfMemoryException GC.Collect() 'liberiamo un po' di memoria, se ce n'è avanzata... My.Computer.FileSystem.WriteAllText("C:\Log.txt", "Warning: memory leak", True) Finally rs2.Close() rs2.Dispose() 'perchè lui niente dispose? End Try End While Catch es As Exception 'io aggiungerei qualcosa di descrittivo... tipo es.Message My.Computer.FileSystem.WriteAllText("C:\Log.txt", "Errore", True) Finally Rs.Close() Rs.Dispose() 'anche lui si merita un dispose Cn.Dispose() Conn.Dispose() Conn2.Dispose() End Try
|
Questo dovrebbe ottimizzare il codice. Nota i Dispose() anche dove avevi i "= Nothing" e il non avere più nulla dichiarato dentro i cicli!
Inoltre Conn2 viene istanziato una volta sola e non a ogni iterazione, mangiandoti risorse a manetta
Sicuramente si può ottimizzare anche a livello algoritmico (tipo fare un'unica query?) ma non sapendo il funzionamento del programma mi riservo di lasciare a te questa parte.
Pensate mentre scrivete il codice!
|
|
vankraster (Member)
Rookie
Messaggi: 32
Iscritto: 05/11/2010
|
[PseudoCodice] - Io uso C#
Io in genere faccio diversamente, l'idea non è quella di fare una query all'interno di ogni ciclo che ti succhia troppe risorse, ma:
riempire un datatable con tutti i valori con :
Datatable DT_RES= EseguiQuery(" Select Stato, Descrizione from Articoli");
Poi dentro il ciclo fai
DT_RES.Select("Descrizione like '"+ Rs("Descrizione") +"'" ) che ti restituisce un'array di datarow.
puoi fare comunque un :
foreach (datarow riga in DT_RES.Select("Descrizione like '%"+ Rs("Descrizione") +"%'" ))
Non ho tempo di buttarti giù il codice, sono al lavoro ma la strada dovrebbe essere questa, e prova a usare gli using senza fare il manual dispose.
fai
Using Cn As New OleDbConnection(Database)
.....
End Using
e non c'è bisogno del dispose.
Ultima modifica effettuata da vankraster il 28/02/2014 alle 12:10 |
|
ACecere (Normal User)
Newbie
Messaggi: 6
Iscritto: 24/02/2014
|
Grazie Mille a tutti!
Ho risolto seguendo il consiglio di Qwertj
|
|
ACecere (Normal User)
Newbie
Messaggi: 6
Iscritto: 24/02/2014
|
Grazie Mille a tutti!
Ho risolto seguendo il consiglio di Qwertj
|
|